#include "../include/SocketHelp.hpp"
#include <vector>
#include <thread>
#include <mutex>

#define BUF_SIZE 1024

std::vector<int> connfdVec;

char* message;
size_t len;
ssize_t readLine;
bool Stop = false;

void GetMessage(int connfd)
{
    char buffer[BUF_SIZE];
    memset(buffer,'\0',BUF_SIZE);
    int length = -1;
    while((length= recv(connfd,buffer,BUF_SIZE-1,0))!=-1)
    {
        printf("Got messgae %s\n",buffer);
        for(auto& iter : connfdVec)
        {
            if(iter != connfd)
            {
                send(iter,buffer,length,0);
            }
        }
    }
    close(connfd);
    return;
}


void GetClient(int sockfd)
{
    while(!Stop)
    {
        struct sockaddr_in address;
        socklen_t length;
        int connfd = accept(sockfd,(struct sockaddr*)&address,&length);
        if(connfd < 0)
        {
            printf("Connect Error!\n");
            break;
        }
        std::mutex mtx;
        mtx.lock();
        connfdVec.push_back(connfd);
        mtx.unlock();
        std::thread clientThread(GetMessage,connfd);
        clientThread.detach();
    }
    printf("Get Client Thread Function End\n");
    return;
}

void StopServer()
{
    printf("Close Thread Start\n");
    while((readLine = getline(&message,&len,stdin))!=-1)
    {
        if(strcmp("Quit\n",message)==0)
        {
            Stop = true;
            printf("Get Quit Command!\n");
            break;
        }
    }
    return;
}


int main(int argc,char** argv)
{
    if(argc<=2)
    {
        printf("Usgae:%s ip_address port_number!",basename(argv[0]));
        return 1;
    }
    const char* ip_address = argv[1];
    int port = atoi(argv[2]);

    //初始化ip_address
    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    //将地址转换为二进制字节
    inet_pton(AF_INET,ip_address,&server_address.sin_addr);
    server_address.sin_port = port;

    int sockfd = socket(PF_INET,SOCK_STREAM,0);
    assert(sockfd >= 0);
    int ret = bind(sockfd,(struct sockaddr*)&server_address,sizeof(server_address));
    assert(ret!=-1);
    ret = listen(sockfd,5);
    std::thread clientListenThread(GetClient,sockfd);
    std::thread closeThread(StopServer);
    clientListenThread.join();
    closeThread.join();

    close(sockfd);
    return 0;
}
